package com.rx.core.service;

import com.rx.core.base.RxBaseConstant;
import com.rx.core.base.RxBaseData;
import com.rx.core.base.RxBaseService;
import com.rx.core.base.RxResponse;
import com.rx.core.enm.RESULT_CODE;
import com.rx.core.handler.*;
import com.rx.core.mode.HandlerContainer;
import com.rx.core.mode.TotalHandlerContainer;
import com.rx.core.util.EmptyChecker;
import com.rx.core.util.RxUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
abstract public class RxBaseAbstractService implements RxBaseService {

    private static boolean canSet(Integer stepLength,Integer newLength){
        return stepLength <= 0 && newLength > 0;
    }
    private static void recordHistory(RxBaseData data,RxHandlerWraper handlerWraper){
        if (data.isHistory() && EmptyChecker.notEmpty(data.getResultData())){
            // 记录处理器结果
            data.setTmpVar(RxBaseConstant.RESULT_PREFIX_KEY + handlerWraper.getHandleName(),data.getResultData());
            data.setHistory(false);
        }
    }
    protected void doHandler(RxBaseData data, List<RxHandlerWraper> handlerWraperList){
        if (data.getResultData() instanceof RxResponse){
            // 提前返回
            return;
        }
        Integer stepLength = 0;
        Integer forLength = 0;
        for (RxHandlerWraper handlerWraper : handlerWraperList) {
            if(stepLength > 0){
                // 选择处理。
                stepLength--;
                continue;
            }
            RxUtil.CheckUtil.condition(handlerWraper.handle(data),
                    RESULT_CODE.MESSAGE,data.getResultMessage());
            // 记录处理历史
            recordHistory(data,handlerWraper);
            if (canSet(stepLength,data.skipLength())){
                stepLength = data.skipLength();
            }
            if (canSet(forLength,data.repeatLength())){
                forLength = data.repeatLength();
            }
            for (;forLength>0;forLength--){
                // 循环处理。
                RxUtil.CheckUtil.condition(handlerWraper.handle(data),
                        RESULT_CODE.MESSAGE,data.getResultMessage());
                // 记录历史结果
                recordHistory(data,handlerWraper);
            }
            data.reset();
        }
    }
    protected boolean doChekcBeforeHandler(RxBaseData data, List<RxHandlerWraper> handlerWraperList){
        if (EmptyChecker.isEmpty(handlerWraperList)){
            return true;
        }
        doHandler(data,handlerWraperList);
        return false;
    }

    /**
     * 如果没有数据返回，直接成功。不用后置处理
     * @param data
     * @return
     */
    private boolean checkResult(RxBaseData data,RxHandlerController controller){
        if (EmptyChecker.isEmpty(data.getResultData())){
            data.setResultData(RxResponse.ok());
            // 无需校验后处理器
            controller.setEnableAfter(false);
            return true;
        }
        return false;
    }
    private boolean checkResult(RxBaseData data){
        if (EmptyChecker.isEmpty(data.getResultData())){
            data.setResultData(RxResponse.ok());
            return true;
        }
        return false;
    }

    private void noRepeatAppend(List<RxHandlerForSort> list,RxHandlerWraper rxHandlerWraper,String url){
        RxHandlerForSort rxHandlerForSort = new RxHandlerForSort(rxHandlerWraper.order(url),rxHandlerWraper);
        if (list.contains(rxHandlerForSort)){
            return;
        }
        list.add(rxHandlerForSort);
    }
    /**
     * 临时调整处理器
     * @param cls
     * @param url
     * @param controller
     * @param configList
     * @return
     */
    private List<RxHandlerWraper> adjustHandler(Class cls,String url,RxHandlerController controller,List<RxHandlerWraper> configList){
        List<RxHandlerForSort> list = new ArrayList<>();


        Map<String, Integer> handlerMap = controller.getForAppend(cls);
        for (Map.Entry<String, Integer> stringIntegerEntry : handlerMap.entrySet()) {
            RxHandlerWraper rxHandlerWraper = TotalHandlerContainer.getHandlerByClass(cls,stringIntegerEntry.getKey());
            Integer order = stringIntegerEntry.getValue();
            if(EmptyChecker.isEmpty(order)){
                order = rxHandlerWraper.order(url);
            }
            list.add(new RxHandlerForSort(order,rxHandlerWraper));
        }
        // 删除处理器
        List<String> removeList = controller.getForRemove(cls);
        for (RxHandlerWraper rxHandlerWraper : configList) {
            if(EmptyChecker.isEmpty(removeList)){
                noRepeatAppend(list,rxHandlerWraper,url);
                continue;
            }
            for (String s : removeList) {
                if(!s.equalsIgnoreCase(rxHandlerWraper.getHandleName())){
                    noRepeatAppend(list,rxHandlerWraper,url);
                }
            }
        }

        return list.stream()
                .distinct()
                .sorted(Comparator.comparingInt(e->e.getOrder()))
                .map(RxHandlerForSort::getHandlerWraper)
                .collect(Collectors.toList());
    }

    /**
     * 统一解决默认抛异常情况
     * @param handlerWraper
     */
    private void handleDefault(handlerMode handlerWraper){
        // 运行默认逻辑
        try {
            handlerWraper.handle();
        }catch (Throwable e){
            log.error(e.getMessage());
            RxUtil.CheckUtil.dealThrowable(e);
        }
    }

    protected void handlerMode(RxBaseData data,HandlerContainer.HandlerAllList handlerAllList,handlerMode handlerWraper){
        //从输入数据中获取处理器控制器
        RxHandlerController controller = data.getHandlerController();
        //TODO: 从redis缓存中获取临时控制器。

        if (EmptyChecker.isEmpty(controller)){
            // 遍历所有前处理器
            doHandler(data,handlerAllList.getPrevList());
            // 遍历所有覆盖处理器
            if (doChekcBeforeHandler(data,handlerAllList.getOverList())){
                // 运行默认逻辑
                handleDefault(handlerWraper);
            }
            if (checkResult(data)){
                return;
            }
            // 遍历所有后处理器
            doHandler(data,handlerAllList.getAfterList());
            return;
        }
        /******************
         * 根据处理器控制器临时调整处理逻辑。
         ******************/

        String url = data.getUrlAnalyse().getUrl();
        // 遍历所有前处理器
        RxUtil.yesDo(controller.getEnablePrev(),()->doHandler(data,
                adjustHandler(RxHandlerPrev.class,url,controller,handlerAllList.getPrevList())));

        if (controller.getEnableOver()){
            // 遍历所有覆盖处理器
            if (doChekcBeforeHandler(data,adjustHandler(RxHandler.class,url,controller,handlerAllList.getOverList()))){
                // 如果条件符合，做后面的调用
                RxUtil.yesDo(controller.getEnableDefault(),()->handleDefault(handlerWraper));
            }
            checkResult(data,controller);
        }else{
            RxUtil.yesDo(controller.getEnableDefault(),()->handleDefault(handlerWraper));
            checkResult(data,controller);
        }
        // doHandler遍历所有后处理器。adjustHandler根据controller重新调整处理器。
        RxUtil.yesDo(controller.getEnableAfter(),()->doHandler(data,
                adjustHandler(RxHandlerAfter.class,url,controller,handlerAllList.getAfterList())));
    }
}
